package com.zlt.bkparking.service.impl;

import com.zlt.bkparking.dto.BackUserDto;
import com.zlt.bkparking.dto.RegisterDto;
import com.zlt.bkparking.dto.LoginDto;
import com.zlt.bkparking.entity.BackUser;
import com.zlt.bkparking.entity.BackUserExample;
import com.zlt.bkparking.entity.Permission;
import com.zlt.bkparking.entity.Role;
import com.zlt.bkparking.mapper.BackUserMapper;
import com.zlt.bkparking.mapper.MyMapper;
import com.zlt.bkparking.service.BackUserService;
import com.zlt.bkparking.shiro.config.JWTToken;
import com.zlt.bkparking.utils.JWTUtil;
import com.zlt.bkparking.utils.MD5Util;
import com.zlt.bkparking.utils.StringUtil;
import com.zlt.bkparking.vo.PermissionVo;
import com.zlt.bkparking.vo.RoleVo;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class BackUserServiceImpl implements BackUserService {

    @Autowired
    private BackUserMapper backUserMapper;

    @Autowired
    private MyMapper myMapper;

    @Override
    public String login(LoginDto loginDto) {
        String username = loginDto.getUsername();
        BackUser backUser = selectUserByUsername(username);
        if (backUser == null){
            throw new RuntimeException("账号或密码错误");
        }
        String s = MD5Util.md5(loginDto.getPassword(), backUser.getBuSalt());
        if (!s.equals(backUser.getBuPassword())){
            throw new RuntimeException("账号或密码错误");
        }
        String token = JWTUtil.sign(backUser.getBuUsername(), backUser.getBuPassword());
        //校验一次token
        SecurityUtils.getSubject().login(new JWTToken(token));

        return token;
    }

    @Override
    @Cacheable(cacheNames = "zltredis",keyGenerator = "userKeyGenerator")
    public BackUser selectUserByUsername(String username) {
        BackUserExample example = new BackUserExample();
        example.createCriteria().andBuUsernameEqualTo(username).andBuStateEqualTo((byte)0);
        List<BackUser> users = backUserMapper.selectByExample(example);
        return (users.isEmpty()&&users==null)?null:users.get(0);
    }

    @Override
    public String addBackUserByDto(RegisterDto registerDto) {
        BackUserExample backUserExample = new BackUserExample();
        //查询数据库中是否存在对应的数据
        ///查询数据库中是否存在username
        backUserExample.or().andBuUsernameEqualTo(registerDto.getBuUsername());
        ///查询数据库中是否存在phone
        backUserExample.or().andBuPhoneEqualTo(registerDto.getBuPhone());
        ///查询数据库中是否存在nickname
        backUserExample.or().andBuNicknameEqualTo(registerDto.getBuNickname());
        List<BackUser> users = backUserMapper.selectByExample(backUserExample);
        if (!users.isEmpty()){
            AtomicReference<String> str = new AtomicReference<>(new String());
            users.forEach(u ->{
                if (registerDto.getBuUsername().equals(u.getBuUsername())){
                    str.set("存在用户名");
                    return;
                }else if (registerDto.getBuPhone().equals(u.getBuPhone())){
                    str.set("存在号码");
                    return;
                }else if (registerDto.getBuNickname().equals(u.getBuNickname())){
                    str.set("存在昵称");
                    return;
                }
            });
            return str.get();
        }else {
            BackUser backUser = new BackUser();
            BeanUtils.copyProperties(registerDto,backUser);
            backUser.setBuSalt(StringUtil.randomStr(6));
            backUser.setBuPassword(MD5Util.md5(backUser.getBuPassword(),backUser.getBuSalt()));

            if (backUserMapper.insertSelective(backUser)>0){
                return "注册成功";
            }else {
                return "注册失败";
            }
        }
    }

    /**
     * 修改BackUser信息
     * @param backUserDto
     * @return
     */
    @Override
    public boolean setBackUserDto(BackUserDto backUserDto) {
        BackUserExample backUserExample = new BackUserExample();
        BackUserExample.Criteria criteria = backUserExample.createCriteria();
        BackUser user = null;

        if (backUserDto.getBuId()==null){
            /// 如果不存在buId
            BackUserExample example = new BackUserExample();
            example.createCriteria().andBuUsernameEqualTo(backUserDto.getBuUsername());
            user = backUserMapper.selectByExample(example).get(0);
        }else {
            /// 如果存在buId
            user = backUserMapper.selectByPrimaryKey(backUserDto.getBuId());
        }

        // 检查目标
        if(backUserDto.getBuUsername()!=null){
            user.setBuUsername(backUserDto.getBuUsername());
        }
        if (backUserDto.getBuPassword()!=null){
            user.setBuPassword(MD5Util.md5(backUserDto.getBuPassword(),user.getBuSalt()));
        }
        if (backUserDto.getBuNickname()!=null){
            user.setBuNickname(backUserDto.getBuNickname());
        }
        if (backUserDto.getBuPhone()!=null){
            user.setBuPhone(backUserDto.getBuPhone());
        }
        if (backUserDto.getBuPhoto()!=null){
            user.setBuPhoto(backUserDto.getBuPhoto());
        }

        return backUserMapper.insertSelective(user)>0;

    }

    /**
     * 注销用户
     * @param username
     * @return
     */
    @Override
    public boolean setStateByUsername(String username) {
        BackUserExample backUserExample = new BackUserExample();
        backUserExample.createCriteria().andBuUsernameEqualTo(username);
        BackUser backUser = backUserMapper.selectByExample(backUserExample).get(0);
        backUser.setBuState((byte)2);
        int i = backUserMapper.updateByPrimaryKey(backUser);
        int j = myMapper.setBURStateByBuId(backUser.getBuId());
        return i+j==2?true:false;
    }

    @Override
    public List<RoleVo> selectRolesVoByBuId(Long buId) {
        List<Role> roles = myMapper.selectRoleByBuId(buId);
        List<RoleVo> roleVos = new ArrayList<>();
        roles.forEach(r -> {
            RoleVo roleVo = new RoleVo();
            BeanUtils.copyProperties(r,roleVo);
            roleVos.add(roleVo);
        });
        return roleVos;
    }

    @Override
    public List<PermissionVo> selectPermissionVoByRoles(List<RoleVo> roleVOS) {
        List<PermissionVo> permissionVos = new ArrayList<>();
        roleVOS.forEach(r -> {
            permissionVos.addAll(selectPermissionVoByRid(r.getRId()));
        });
        return permissionVos;
    }

    @Override
    @Cacheable(cacheNames = "zltredis",keyGenerator = "permissionRidKeyGenerator")
    public List<PermissionVo> selectPermissionVoByRid(Integer rid){


        List<Permission> permissions = myMapper.selectPermissionByRid(rid);


        List<PermissionVo> permissionVos = new ArrayList<>();
        permissions.forEach(p->{
            PermissionVo permissionVo = new PermissionVo();
            BeanUtils.copyProperties(p,permissionVo);
            permissionVos.add(permissionVo);
        });
        return permissionVos;
    }
}
